using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using WPCoco;

namespace WPCoco
{
    /// <summary>
    /// Extesion for using XNA SpriteBatch class
    /// </summary>
    public static class SpriteBatchExtensions
    {
        #region Ref Version

        public static void Draw(this SpriteBatch spriteBatch, ref TextureFrame frame, Vector2 position)
        {
            position.X += frame.TextureTrim.Left;
            position.Y += frame.TextureTrim.Top;
            spriteBatch.Draw(frame.Texture, position, frame.TextureRegion, Color.White);
        }

        public static void Draw(this SpriteBatch spriteBatch, ref TextureFrame frame, Vector2 position, Color color)
        {
            position.X += frame.TextureTrim.Left;
            position.Y += frame.TextureTrim.Top;
            spriteBatch.Draw(frame.Texture, position, frame.TextureRegion, color);
        }

        public static void Draw(this SpriteBatch spriteBatch, ref TextureFrame frame, Vector2 position, Color color, float depth)
        {
            position.X += frame.TextureTrim.Left;
            position.Y += frame.TextureTrim.Top;
            spriteBatch.Draw(frame.Texture, position, frame.TextureRegion, color, 0, Vector2.Zero, 1, SpriteEffects.None, depth);
        }

        public static void Draw(this SpriteBatch spriteBatch, ref TextureFrame frame, Vector2 position, Vector2 anchor, float depth)
        {
            position = new Vector2(position.X - (frame.TextureRegion.Width + frame.TextureTrim.TotalWidth) * anchor.X,
                                   position.Y - (frame.TextureRegion.Height + frame.TextureTrim.TotalHeight) * anchor.Y);
            position.X += frame.TextureTrim.Left;
            position.Y += frame.TextureTrim.Top;
            spriteBatch.Draw(frame.Texture,
                             position,
                             frame.TextureRegion,
                             Color.White,
                             0,
                             Vector2.Zero,
                             1,
                             SpriteEffects.None,
                             depth);
        }

        public static void Draw(this SpriteBatch spriteBatch, ref TextureFrame frame, Vector2 position, Vector2 anchor, float depth, Color color)
        {
            position = new Vector2(position.X - (frame.TextureRegion.Width + frame.TextureTrim.TotalWidth) * anchor.X,
                                   position.Y - (frame.TextureRegion.Height + frame.TextureTrim.TotalHeight) * anchor.Y);
            position.X += frame.TextureTrim.Left;
            position.Y += frame.TextureTrim.Top;
            spriteBatch.Draw(frame.Texture,
                             position,
                             frame.TextureRegion,
                             color,
                             0,
                             Vector2.Zero,
                             1,
                             SpriteEffects.None,
                             depth);
        }

        public static void Draw(this SpriteBatch spriteBatch, ref TextureFrame frame, Vector2 position, Vector2 anchor, float scale, float depth, Color color)
        {
            position = new Vector2(position.X - (frame.TextureRegion.Width + frame.TextureTrim.TotalWidth) * anchor.X * scale,
                                   position.Y - (frame.TextureRegion.Height + frame.TextureTrim.TotalHeight) * anchor.Y * scale);
            position.X += frame.TextureTrim.Left * scale;
            position.Y += frame.TextureTrim.Top * scale;

            Rectangle rect = new Rectangle((int)position.X, 
                                           (int)position.Y,
                                           (int)((frame.TextureRegion.Width + frame.TextureTrim.TotalWidth) * scale),
                                           (int)((frame.TextureRegion.Height + frame.TextureTrim.TotalHeight) * scale));

            spriteBatch.Draw(frame.Texture,
                             rect,
                             frame.TextureRegion,
                             color,
                             0,
                             Vector2.Zero,
                             SpriteEffects.None,
                             depth);
        }

        public static void Draw(this SpriteBatch spriteBatch, ref TextureFrame frame, Vector2 position, Vector2 anchor, Vector2 scale, float rotation, float depth, Color color)
        {
            position.X += frame.TextureTrim.Left;
            position.Y += frame.TextureTrim.Top;

            Size s = frame.Size;
            anchor = new Vector2(anchor.X * s.Width, anchor.Y * s.Height);

            spriteBatch.Draw(frame.Texture,
                             position,
                             frame.TextureRegion,
                             color,
                             MathHelper.ToRadians(rotation),
                             anchor,
                             scale,
                             SpriteEffects.None,
                             depth);
        }

        #endregion

        #region Normal Version

        public static void Draw(this SpriteBatch spriteBatch, TextureFrame frame, Vector2 position)
        {
            position.X += frame.TextureTrim.Left;
            position.Y += frame.TextureTrim.Top;
            spriteBatch.Draw(frame.Texture, position, frame.TextureRegion, Color.White);
        }

        public static void Draw(this SpriteBatch spriteBatch, TextureFrame frame, Vector2 position, Color color)
        {
            position.X += frame.TextureTrim.Left;
            position.Y += frame.TextureTrim.Top;
            spriteBatch.Draw(frame.Texture, position, frame.TextureRegion, color);
        }

        public static void Draw(this SpriteBatch spriteBatch, TextureFrame frame, Vector2 position, Color color, float depth)
        {
            position.X += frame.TextureTrim.Left;
            position.Y += frame.TextureTrim.Top;
            spriteBatch.Draw(frame.Texture, position, frame.TextureRegion, color, 0, Vector2.Zero, 1, SpriteEffects.None, depth);
        }

        public static void Draw(this SpriteBatch spriteBatch, TextureFrame frame, Vector2 position, Vector2 anchor, float depth)
        {
            position = new Vector2(position.X - (frame.TextureRegion.Width + frame.TextureTrim.TotalWidth) * anchor.X,
                                   position.Y - (frame.TextureRegion.Height + frame.TextureTrim.TotalHeight) * anchor.Y);
            position.X += frame.TextureTrim.Left;
            position.Y += frame.TextureTrim.Top;
            spriteBatch.Draw(frame.Texture,
                             position,
                             frame.TextureRegion,
                             Color.White,
                             0,
                             Vector2.Zero,
                             1,
                             SpriteEffects.None,
                             depth);
        }

        public static void Draw(this SpriteBatch spriteBatch, TextureFrame frame, Vector2 position, Vector2 anchor, float depth, Color color)
        {
            position = new Vector2(position.X - (frame.TextureRegion.Width + frame.TextureTrim.TotalWidth) * anchor.X,
                                   position.Y - (frame.TextureRegion.Height + frame.TextureTrim.TotalHeight) * anchor.Y);
            position.X += frame.TextureTrim.Left;
            position.Y += frame.TextureTrim.Top;
            spriteBatch.Draw(frame.Texture,
                             position,
                             frame.TextureRegion,
                             color,
                             0,
                             Vector2.Zero,
                             1,
                             SpriteEffects.None,
                             depth);
        }

        public static void Draw(this SpriteBatch spriteBatch, TextureFrame frame, Vector2 position, Vector2 anchor, float scale, float depth, Color color)
        {
            position = new Vector2(position.X - (frame.TextureRegion.Width + frame.TextureTrim.TotalWidth) * anchor.X * scale,
                                   position.Y - (frame.TextureRegion.Height + frame.TextureTrim.TotalHeight) * anchor.Y * scale);
            position.X += frame.TextureTrim.Left * scale;
            position.Y += frame.TextureTrim.Top * scale;

            Rectangle rect = new Rectangle((int)position.X,
                                           (int)position.Y,
                                           (int)((frame.TextureRegion.Width) * scale),
                                           (int)((frame.TextureRegion.Height) * scale));

            spriteBatch.Draw(frame.Texture,
                             rect,
                             frame.TextureRegion,
                             color,
                             0,
                             Vector2.Zero,
                             SpriteEffects.None,
                             depth);
        }

        public static void Draw(this SpriteBatch spriteBatch, TextureFrame frame, Vector2 position, Vector2 anchor, float scale, float rotation, float depth, Color color)
        {
            position.X += frame.TextureTrim.Left;
            position.Y += frame.TextureTrim.Top;

            Size s = frame.Size;
            anchor = new Vector2(anchor.X * s.Width, anchor.Y * s.Height); 

            spriteBatch.Draw(frame.Texture,
                             position,
                             frame.TextureRegion,
                             color,
                             MathHelper.ToRadians(rotation),
                             anchor,
                             scale,
                             SpriteEffects.None,
                             depth);
        }

        public static void Draw(this SpriteBatch spriteBatch, TextureFrame frame, Vector2 position, Vector2 anchor, Vector2 scale, float rotation, float depth, Color color)
        {
            position.X += frame.TextureTrim.Left;
            position.Y += frame.TextureTrim.Top;

            Size s = frame.Size;
            anchor = new Vector2(anchor.X * s.Width, anchor.Y * s.Height);

            spriteBatch.Draw(frame.Texture,
                             position,
                             frame.TextureRegion,
                             color,
                             MathHelper.ToRadians(rotation),
                             anchor,
                             scale,
                             SpriteEffects.None,
                             depth);
        }


        public static void Draw(this SpriteBatch spriteBatch, TextureFrame framea, TextureFrame frameb, Vector2 position, float depth, float amount)
        {
            Vector2 position2 = position;
            position.X += framea.TextureTrim.Left; position.Y += framea.TextureTrim.Top;
            position2.X += frameb.TextureTrim.Left; position2.Y += frameb.TextureTrim.Top;
            Color a = Color.White;
            spriteBatch.Draw(framea.Texture, position, framea.TextureRegion, a, 0, Vector2.Zero, 1, SpriteEffects.None, depth + 0.00001f);
            Color b = new Color(amount, amount, amount, amount);
            spriteBatch.Draw(frameb.Texture, position2, frameb.TextureRegion, b, 0, Vector2.Zero, 1, SpriteEffects.None, depth);
        }

        public static void Draw(this SpriteBatch spriteBatch, TextureFrame framea, TextureFrame frameb, Vector2 position, float depth, float amount, Color color)
        {
            Vector2 position2 = position;
            position.X += framea.TextureTrim.Left; position.Y += framea.TextureTrim.Top;
            position2.X += frameb.TextureTrim.Left; position2.Y += frameb.TextureTrim.Top;
            //Color a = Color.Lerp(color, Color.Transparent, 1 - amount);
            Color a = color;
            spriteBatch.Draw(framea.Texture, position, framea.TextureRegion, a, 0, Vector2.Zero, 1, SpriteEffects.None, depth + 0.00001f);
            Color b = Color.Lerp(color, Color.Transparent, amount);
            spriteBatch.Draw(frameb.Texture, position2, frameb.TextureRegion, b, 0, Vector2.Zero, 1, SpriteEffects.None, depth);
        }

        public static void Draw(this SpriteBatch spriteBatch, TextureFrame framea, TextureFrame frameb, Vector2 position, Vector2 anchor, float depth, float amount)
        {
            position = new Vector2(position.X - (framea.TextureRegion.Width + framea.TextureTrim.TotalWidth) * anchor.X,
                                   position.Y - (framea.TextureRegion.Height + framea.TextureTrim.TotalHeight) * anchor.Y);

            Vector2 position2 = position;
            position.X += framea.TextureTrim.Left; position.Y += framea.TextureTrim.Top;
            position2.X += frameb.TextureTrim.Left; position2.Y += frameb.TextureTrim.Top;

            //Color a = new Color(1 - amount, 1 - amount, 1 - amount, 1 - amount);
            Color a = Color.White;
            spriteBatch.Draw(framea.Texture, position, framea.TextureRegion, a, 0, Vector2.Zero, 1, SpriteEffects.None, depth + 0.00001f);
            Color b = new Color(amount, amount, amount, amount);
            spriteBatch.Draw(frameb.Texture, position2, frameb.TextureRegion, b, 0, Vector2.Zero, 1, SpriteEffects.None, depth);
        }

        public static void Draw(this SpriteBatch spriteBatch, TextureFrame framea, TextureFrame frameb, Vector2 position, Vector2 anchor, float depth, float amount, Color color)
        {
            position = new Vector2(position.X - (framea.TextureRegion.Width + framea.TextureTrim.TotalWidth) * anchor.X,
                                   position.Y - (framea.TextureRegion.Height + framea.TextureTrim.TotalHeight) * anchor.Y);

            Vector2 position2 = position;
            position.X += framea.TextureTrim.Left; position.Y += framea.TextureTrim.Top;
            position2.X += frameb.TextureTrim.Left; position2.Y += frameb.TextureTrim.Top;

            //Color a = Color.Lerp(color, Color.Transparent, 1 - amount);
            Color a = color;
            spriteBatch.Draw(framea.Texture, position, framea.TextureRegion, a, 0, Vector2.Zero, 1, SpriteEffects.None, depth + 0.00001f);
            Color b = Color.Lerp(color, Color.Transparent, amount);
            spriteBatch.Draw(frameb.Texture, position2, frameb.TextureRegion, b, 0, Vector2.Zero, 1, SpriteEffects.None, depth);
        }
        #endregion
    }
}
